package com.csot.ry.controller;

import java.io.File;
import java.io.IOException;
import java.math.RoundingMode;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.map.BiMap;
import cn.hutool.core.text.csv.CsvUtil;
import cn.hutool.core.text.csv.CsvWriter;
import cn.hutool.core.util.NumberUtil;
import com.csot.common.core.domain.entity.SysDictData;
import com.csot.common.exception.ServiceException;
import com.csot.common.utils.DictUtils;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.ehcache.CacheKit;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.csot.ry.domain.TTotalSegment;
import com.csot.ry.poi.ExcelUtilSub;
import com.csot.ry.service.ITTotalSegmentService;
import com.csot.ry.util.CacheKitUtil;
import com.csot.common.annotation.Log;
import com.csot.common.constant.HttpStatus;
import com.csot.common.core.controller.BaseController;
import com.csot.common.core.domain.AjaxResult;
import com.csot.common.core.domain.entity.SysUser;
import com.csot.common.core.page.TableDataInfo;
import com.csot.common.enums.BusinessType;
import com.csot.common.utils.StringUtils;
import com.csot.common.utils.poi.ExcelUtil;

import cn.hutool.core.util.StrUtil;

/**
 * 省级ip段Controller
 *
 * @author 刘沙
 * @date 2022-05-31
 */
@RestController
@RequestMapping("/ipmanagement/totalsegment")
public class TTotalSegmentController extends BaseController {
    @Autowired
    private ITTotalSegmentService tTotalSegmentService;

    /**
     * 查询省级ip段列表
     */
    @PreAuthorize("@ss.hasPermi('ipmanagement:totalsegment:list')")
    @GetMapping("/list/{type}")
    public TableDataInfo list(TTotalSegment tTotalSegment, @PathVariable("type") String type) {
        try {
            startPage();
            tTotalSegment.setIpType(type.toLowerCase());
            List<TTotalSegment> list = tTotalSegmentService.selectTTotalSegmentList(tTotalSegment);
            return getDataTable(list);
        } catch (Exception e) {
            TableDataInfo rspData = new TableDataInfo();
            rspData.setCode(HttpStatus.ERROR);
            rspData.setMsg(StringUtils.isNotEmpty(e.getMessage()) ? "请联系管理员：" + e.getMessage() : "查询失败，请联系管理员");
            rspData.setRows(null);
            rspData.setTotal(0);
            return rspData;
        }

    }

    /**
     * 导出省级ip段列表
     */
    @PreAuthorize("@ss.hasPermi('ipmanagement:totalsegment:export')")
    @Log(title = "省级ip段", businessType = BusinessType.EXPORT)
    @PostMapping("/export/{type}")
    public void export(HttpServletResponse response, TTotalSegment tTotalSegment, @PathVariable("type") String type) {
        String parentId = getLoginUser().getUser().getDept().getParentId() + "";
        if (CacheKitUtil.ip_dept != null && StrUtil.isNotEmpty(parentId) && !"null".equals(parentId)) {
            tTotalSegment.setIpCity(CacheKitUtil.ip_dept.get(parentId + ""));
        }
        tTotalSegment.setIpType(type.toLowerCase());
        List<TTotalSegment> list = tTotalSegmentService.selectTTotalSegmentList(tTotalSegment);
        for (TTotalSegment t : list) {
            t.setIpType(CacheKitUtil.ip_type.get(t.getIpType()));
            t.setIpCity(CacheKitUtil.ip_city.get(t.getIpCity()));
            t.setIpStatus(CacheKitUtil.ip_status.get(t.getIpStatus()));
//            t.setIpStatus(t.getIpStatus().equals("on")?"启用":"停用");
        }
        ExcelUtil<TTotalSegment> util = new ExcelUtil<TTotalSegment>(TTotalSegment.class);
        util.exportExcel(response, list, "省级ip段数据");
    }

    @Log(title = "省级ip段导入", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('ipmanagement:totalsegment:import')")
    @PostMapping("/importData/{type}")
    public AjaxResult importData(MultipartFile file, boolean updateSupport, @PathVariable("type") String type) throws Exception {
        ExcelUtilSub<TTotalSegment> util = new ExcelUtilSub<TTotalSegment>(TTotalSegment.class);
        List<TTotalSegment> tTotalSegmentList = util.importExcel(file.getInputStream());
        for (TTotalSegment tTotalSegment : tTotalSegmentList) {
            tTotalSegment.setIpType(type.toLowerCase());
        }
        SysUser user = getLoginUser().getUser();
        return toAjax(tTotalSegmentService.importTotalSegment(tTotalSegmentList, updateSupport, user));
    }

    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        try {
            String path = System.getProperty("user.dir");
            path = path + File.separator + "Template" + File.separator + "totalsegment.xlsx";
            IOUtils.write(Files.readAllBytes(Paths.get(path)), response.getOutputStream());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            logger.error("下载ip段模块异常", e);
        }
    }

    /**
     * 获取省级ip段详细信息
     */
    @PreAuthorize("@ss.hasPermi('ipmanagement:totalsegment:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return AjaxResult.success(tTotalSegmentService.selectTTotalSegmentById(id));
    }

    /**
     * 新增省级ip段
     */
    @PreAuthorize("@ss.hasPermi('ipmanagement:totalsegment:add')")
    @Log(title = "省级ip段", businessType = BusinessType.INSERT)
    @PostMapping(value = "/{type}")
    public AjaxResult add(@RequestBody TTotalSegment tTotalSegment, @PathVariable("type") String type) {
        tTotalSegment.setIpType(type.toLowerCase());
        return toAjax(tTotalSegmentService.insertTTotalSegment(tTotalSegment));
    }

    /**
     * 修改省级ip段
     */
    @PreAuthorize("@ss.hasPermi('ipmanagement:totalsegment:edit')")
    @Log(title = "省级ip段", businessType = BusinessType.UPDATE)
    @PutMapping(value = "/{type}")
    public AjaxResult edit(@RequestBody TTotalSegment tTotalSegment, @PathVariable("type") String type) {
        tTotalSegment.setIpType(type.toLowerCase());
        return toAjax(tTotalSegmentService.updateTTotalSegment(tTotalSegment));
    }

    /**
     * 删除省级ip段
     */
    @PreAuthorize("@ss.hasPermi('ipmanagement:totalsegment:remove')")
    @Log(title = "省级ip段", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(tTotalSegmentService.deleteTTotalSegmentByIds(ids));
    }


    /**
     * 导出省级ip段列表
     */
    @PreAuthorize("@ss.hasPermi('ipmanagement:totalsegment:export')")
    @Log(title = "省级ip段", businessType = BusinessType.EXPORT)
    @PostMapping("/export1/{type}")
    public void exportTj(HttpServletResponse response, @PathVariable("type") String type) throws IOException {

        List<Record> tlist = Db.find("select ip_city,sum(ip_end_i - ip_start_i +1) as ips from t_total_segment group by ip_city");
        List<Record> xlist = Db.find("select ip_city,sum(ip_end_i - ip_start_i +1) as ips from t_city_segment group by ip_city");
        List<Record> clist = Db.find("select ip_city,sum(ip_end_i - ip_start_i +1) as ips from t_coarse_segment group by ip_city");
        List<SysDictData> sysDictData = DictUtils.getDictCache("ip_city");

        ListUtil.sort(tlist, new Comparator<Record>() {
            @Override
            public int compare(Record o1, Record o2) {
                SysDictData s1 = sysDictData.stream().filter(f -> f.getDictValue().equals(o1.getStr("ip_city"))).findFirst().get();
                SysDictData s2 = sysDictData.stream().filter(f -> f.getDictValue().equals(o2.getStr("ip_city"))).findFirst().get();
                return (int) (s1.getDictSort() - s2.getDictSort());
            }
        });

        List<TempPojo> result = new ArrayList<>();
        for (Record r : tlist) {
            TempPojo tp = new TempPojo();
            tp.setCity(r.getStr("ip_city"));
            tp.setZs(r.getStr("ips"));
            result.add(tp);
        }
        for (TempPojo tp : result) {
            tp.setXld("0");
            for (Record r : xlist) {
                if (r.getStr("ip_city").equalsIgnoreCase(tp.getCity())) {
                    tp.setXld(r.getStr("ips"));
                    break;
                }
            }
            tp.setXldzb(NumberUtil.decimalFormat("0.00%",
                    NumberUtil.toBigDecimal(tp.getXld()).divide(NumberUtil.toBigDecimal(tp.getZs()), 4, RoundingMode.HALF_UP))
            );
        }

        for (TempPojo tp : result) {
            tp.setCld("0");
            for (Record r : clist) {
                if (r.getStr("ip_city").equalsIgnoreCase(tp.getCity())) {
                    tp.setCld(r.getStr("ips"));
                    break;
                }
            }
            tp.setCldzb(NumberUtil.decimalFormat("0.00%",
                    NumberUtil.toBigDecimal(tp.getCld()).divide(NumberUtil.toBigDecimal(tp.getZs()), 4, RoundingMode.HALF_UP))
            );
        }
        BiMap<String, String> map = CacheKit.get("dict-data", "ip_city");
        try {
            File file = FileUtil.createTempFile();
            System.out.println(response.getCharacterEncoding());
            CsvWriter csv = CsvUtil.getWriter(file, Charset.forName("GBK"));
            csv.writeHeaderLine("地市", "总量", "已录入细粒度", "细粒度录入占比", "已录入粗粒度", "粗粒度录入占比");
            for (TempPojo tp : result) {
                csv.writeLine(map.get(tp.getCity()), tp.getZs(), tp.getXld(), tp.getXldzb(), tp.getCld(), tp.getCldzb());
            }
            csv.close();
            IoUtil.write(response.getOutputStream(), true, FileUtil.readBytes(file));
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(e.getMessage());
        }
    }

    static class TempPojo {
        String city;
        String zs;
        String xld;
        String cld;
        String xldzb;
        String cldzb;

        public String getCity() {
            return city;
        }

        public void setCity(String city) {
            this.city = city;
        }

        public String getZs() {
            return zs;
        }

        public void setZs(String zs) {
            this.zs = zs;
        }

        public String getXld() {
            return xld;
        }

        public void setXld(String xld) {
            this.xld = xld;
        }

        public String getCld() {
            return cld;
        }

        public void setCld(String cld) {
            this.cld = cld;
        }

        public String getXldzb() {
            return xldzb;
        }

        public void setXldzb(String xldzb) {
            this.xldzb = xldzb;
        }

        public String getCldzb() {
            return cldzb;
        }

        public void setCldzb(String cldzb) {
            this.cldzb = cldzb;
        }
    }

}
